package write_file

import (
	"encoding/csv"
	"fmt"
	"os"
	m "spider/my_logger"
)

type OptionFunc func(*WriteFile)

func WithFileName(name string) OptionFunc {
	return func(o *WriteFile) {
		o.fileName = name
	}
}

type WriteFile struct {
	done     chan struct{}
	ch       chan *CityInfo
	fileName string
}

func NewWriteFile(opts ...OptionFunc) (wf *WriteFile) {
	wf = &WriteFile{
		done: make(chan struct{}),
		ch:   make(chan *CityInfo, 1000),
	}
	for _, o := range opts {
		o(wf)
	}
	if wf.fileName == "" {
		wf.fileName = "./output.csv"
	}
	return
}
func (w *WriteFile) Write(data *CityInfo) {
	w.ch <- data
}

func (w *WriteFile) IsDone() {
	close(w.ch)
}

func (w *WriteFile) Wait() {
	m.Info("writeFile wait!")
	<-w.done
}

func (w *WriteFile) Start() {
	go func() {
		defer func() {
			w.done <- struct{}{}
		}()
		outputFile, outputError := os.OpenFile(w.fileName, os.O_WRONLY|os.O_CREATE, 0666)
		if outputError != nil {
			m.Panic(outputError.Error())
			return
		}
		defer outputFile.Close()
		outputWriter := csv.NewWriter(outputFile)
		defer outputWriter.Flush()
		outputWriter.Write([]string{"编码", "名称", "父级", "等级"})

		for item := range w.ch {
			outputWriter.Write([]string{
				item.Code, item.Name, item.Parent, fmt.Sprintf("%d", item.Level),
			})
		}

	}()
}

type CityInfo struct {
	Code   string
	Name   string
	Level  int
	Parent string
}

func (c *CityInfo) String() string {
	if c == nil {
		return ""
	}
	return fmt.Sprintf("%s|%s|%s|%d", c.Code, c.Name, c.Parent, c.Level)
}
